package com.ijtunes.utils;

/**
 * Different properties used in iJTunes.
 * @author Michael Sena
 * @version 1.1 (Adopted for iJTunes)
 * @date 01/07/2010
 */
public enum Property {
    /** FEATURE: Look up on Last.fm for the genre of an artist. */
    GENRE_SEARCH(Area.GENRE_SEARCH_NAME, Value.ENABLED, Value.FALSE),
    /** [genreSearch]: Whether to replace the existing genre or not. */
    REPLACE_EXISTING_GENRE(Area.GENRE_SEARCH_NAME, "replaceExistingGenre",
        Value.TRUE),
    /** [genreSearch]: Selection of tags to replace with a standard tag. */
    REPLACEMENT_TAGS(Area.GENRE_SEARCH_NAME,
        "replacementTags",
        "dark electro|c;harsh ebm,"
        + "nu metal|c;alternative metal;rapcore,"
        + "dark electro|c;ebm;cyberpunk;industrial;nyhc,"
        + "r&b;rnb,"
        + "christian|c;worship,"
        + "hip-hop;hiphop,"
        + "happy hardcore|c;happy;eurodance;blues;danny diablo;euro-techno;"
            + "electronic;nrg;old school hardcore;happy rave;fusion;j-rock;"
            + "hardcore;gabber;gabba,"
        + "christian;contemporary christian;christian rock,"
        + "video game music;game music;game remixes;video game remixes;"
            + "video game;game soundtrack,"
        + "mixes;skitzmix"
        ),
    /** [genreSearch]: Tags to ignore/skip. */
    SKIPPED_TAGS(Area.GENRE_SEARCH_NAME,
        "skippedTags",
        "50s,60s,70s,80s,90s,american,australian,big beat,british,canadian,"
        + "chillout,club,dance,deutsch,dutch,electronic,electronica,"
        + "experimental,female,female vocalists,french,game,german,girls aloud,"
        + "italian,j-core,japanese,metal,nhyc,nrg,oc remix,ocremix,polish,rave,"
        + "remix,rock,saxophone,singer-songwriter,soundtrack,swedish,techno,"
        + "tiesto,trance,wicked"
        ),

    /** FEATURE: Scan a directory and add files into iTunes if they aren't in
                 the library already. */
    ADD_NEW_FILES(Area.ADD_NEW_FILES_NAME, Value.ENABLED, Value.TRUE),
    /** [addNewFiles]: File extensions to add. */
    MUSIC_EXTENSIONS(Area.ADD_NEW_FILES_NAME, "fileExtensions",
        ".mp3,.m4a,.wav"),
    /** [addNewFiles]: Directories to scan. */
    SCAN_DIRECTORIES(Area.ADD_NEW_FILES_NAME, "directories",
      "C:\\processed"),

    /** FEATURE: Rename files that don't match a particular pattern. */
    ORGANISE_FILES(Area.ORGANISE_FILES_NAME, Value.ENABLED, Value.FALSE),
    /** [organiseFiles]: Regular expression to use. */
    ORGANISING_EXPRESSION(Area.ORGANISE_FILES_NAME, "expression",
        "%root%\\%albumartist%\\%album%\\%tracknum2% - %name%.%extension%"),
    /** [organiseFiles]: Root folder to base files on. */
    ORGANISING_ROOT(Area.ORGANISE_FILES_NAME, "root", "C:\\processed"),
    /** [organiseFiles]: Whether to only allow ASCII characters when naming. */
    ASCII_ONLY(Area.ORGANISE_FILES_NAME, "asciiOnly", Value.FALSE),
    /** [organiseFiles]: Whether to update iTunes with the new location. */
    UPDATE_ITUNES(Area.ORGANISE_FILES_NAME, "updateITunes", Value.TRUE),
    /** [organiseFiles]: Whether 'Artist' is used if 'AlbumArtist' is blank. */
    USE_ARTIST_IF_BLANK(Area.ORGANISE_FILES_NAME, "useArtistIfBlank",
        Value.TRUE),

    /** FEATURE: Synchronise iTunes play count with Last.fm. */
    SYNC_PLAYCOUNT(Area.SYNC_PLAYCOUNT_NAME, Value.ENABLED, Value.FALSE),

    /** FEATURE: Delete missing tracks from iTunes. */
    DELETE_MISSING(Area.DELETE_MISSING_NAME, Value.ENABLED, Value.TRUE),

    /** FEATURE: Advanced location of duplicates in a collection. */
    FIND_DUPLICATES(Area.FIND_DUPLICATES_NAME, Value.ENABLED, Value.TRUE),

    /** API key to use when using last.fm services. */
    APIKEY(Area.MISC, "lastfm.apikey", "b25b959554ed76058ac220b7b2e0a026"),
    /** Last.fm username. */
    USERNAME(Area.MISC, "lastfm.username", "mikesena"),
    /** Whether to backup the skippedTags property if it becomes corrupted. */
    BACKUP_SKIPPED_TAGS(Area.MISC, "backupSkippedTags", null),
    /* TODO: Add properties for verbose logging output, logging output
             and displaying summary */
    /** Level of detail in the output log. */
    VERBOSE_OUTPUT(Area.MISC, "verboseOutput", Value.FALSE);

    /**
     * Default constructor for a property.
     * @param propArea Group to update.
     * @param propName Name of the property.
     * @param propDefaultValue Default value of the property.
     */
    private Property(final String propArea, final String propName,
        final String propDefaultValue) {
        name = propArea + "." + propName;
        defaultValue = propDefaultValue;
    }

    /** Name of the property. */
    private final String name;
    /** Default value of the property. */
    private final String defaultValue;

    @Override
    public String toString() {
        return this.name;
    }

    /**
     * Get the default value of a property.
     * @return String representation of the default value
     */
    public String getDefaultValue() {
        return this.defaultValue;
    }

    /** Area/group of settings. */
    abstract static class Area {
        /** Settings related to adding new files to iTunes. */
        public static final String ADD_NEW_FILES_NAME = "addNewFiles";
        /** Settings related to deleting missing entries from iTunes. */
        public static final String DELETE_MISSING_NAME = "deleteMissing";
        /** Settings related to finding duplicate tracks. */
        public static final String FIND_DUPLICATES_NAME = "findDuplicates";
        /** Settings related to searching for the track's genre. */
        public static final String GENRE_SEARCH_NAME = "genreSearch";
        /** Settings related to organising files. */
        public static final String ORGANISE_FILES_NAME = "organiseFiles";
        /** Settings related to syncing the Last.fm playcount with iTunes. */
        public static final String SYNC_PLAYCOUNT_NAME = "syncPlaycount";
        /** Other related settings. */
        public static final String MISC = "misc";

        /** Default private constructor. */
        private Area() { }
    }

    /** Some static default values. */
    abstract static class Value {
        /** Property name for seeing if a feature is to be used. */
        public static final String ENABLED = "enabled";
        /** String representation of 'true'. */
        public static final String TRUE = Boolean.toString(true);
        /** String representation of 'false'. */
        public static final String FALSE = Boolean.toString(false);

        /** Default private constructor. */
        private Value() { }
    }
}